# -*- coding:utf-8 -*-

## =====================================================================
## Copyright (C) 2007-2011  Jean-Philippe GOLAY
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## =====================================================================


from Tkinter import *
import Pmw
from tkMessageBox import *

from Persistance import *
from iCalendar import CalendarGUI
from iStaff import StaffListGUI
from iNotes import NotesGUI
from iTime import TimePopupGUI

class TimeSheetStaffGUI(Toplevel):
	def __init__(self, parent=None, balloon=None, path=None, log=None):
		Toplevel.__init__(self, parent)
		self.parent=parent
		self.grab_set()
		self.transient(self.master)
		self.resizable(width=False, height=False)
		self.title(u"Emplois du temps")
		self.balloon=balloon
		self.imgSave=PhotoImage(file="img/save_icon.gif")
		self.imgDelete=PhotoImage(file="img/delete_icon.gif")
		self.imgCalendar=PhotoImage(file="img/calendar.gif")
		self.imgTime=PhotoImage(file="img/time_icon.gif")
		self.imgNotes=PhotoImage(file="img/edit.gif")
		self.imgSearch=PhotoImage(file="img/search_icon.gif")
		self.imgNew=PhotoImage(file="img/add_alternative_icon.gif")
		self.hoursListCB = Glob.HOURS_LIST
		self.minutesListCB = Glob.MINUTES_LIST
		self.path=path
		self.log=log
		# Afficher un icon personnalisé
		try:
			if os.name =="posix":
				img = PhotoImage(file=self.path+"/icons/Time-icon.gif")
				self.tk.call("wm", "iconphoto", self._w, img)
			else:
				self.iconbitmap(default=self.path+"/icons/Time-icon.gif")
		except TclError:
			self.log.warning("Le window manager ne supporte pas l'icône que je veux lui mettre...")
		self.log.info("\tTimeSheetStaffGUI\tStart")
		self.makeTimeSheetStaff()

    # DEBUT de la gestion du module TimeSheetStaff ---------------------------------------------------------------------------------------------
    #~ def searchStaffTSS(self, event=None):
        #~ self.listStaffTSS.delete(0,END)
        #~ self.idListStaffTSS = []
        #~ if self.searchStaffTSSValue.get() != "":
            #~ result = Staff.select(Staff.q.lname.startswith(self.searchStaffTSSValue.get().encode("utf-8")), orderBy=Staff.q.lname)
            #~ for row in result:
                #~ self.listStaffTSS.insert(END, row.lname+" - "+row.fname+" - ("+row.grade+")")
                #~ self.idListStaffTSS.append(row.id)
        #~ else:
            #~ result = Staff.select(orderBy=Staff.q.lname)
            #~ for row in result:
                #~ self.listStaffTSS.insert(END, row.lname+" - "+row.fname+" - ("+row.grade+")")
                #~ self.idListStaffTSS.append(row.id)

	def clearFieldTSS(self):
		# Mise a zéro des champs de la fiche emplois du temps
		self.tssValues[0].set("")
		self.tssValues[1].set("")
		self.tssValues[2].set("")
		self.tssValues[3].set("")
		self.tssValues[4].set("")
		self.tssValues[5].set("")
		self.tssValues[6].set(u"E")
		self.tssValues[7].set("")
		# Remise à zéro des ComboBox
		self.statusTSSCB.selectitem(0)
		self.hourInTSSCB.selectitem(0)
		self.minInTSSCB.selectitem(0)
		self.hourOutTSSCB.selectitem(0)
		self.minOutTSSCB.selectitem(0)
		self.tssHourIn=StringVar()
		self.tssMinuteIn=StringVar()
		self.tssHourOut=StringVar()
		self.tssMinuteOut=StringVar()
		self.listObject=[Staff]

	def selectTimeSheetStaff(self, event):
		 if  self.searchTaskEt.config()["state"][4] == "normal":
			result = TimeSheetStaff.select(TimeSheetStaff.q.id==self.idListTSS[int(self.listTSS.curselection()[0])])
			for row in result:
				self.selectedTSS = row
			self.tssValues[1].set(self.selectedTSS.description)
			self.tssValues[6].set(self.selectedTSS.checked)
			self.tssValues[7].set(self.selectedTSS.notes)
			self.listObject[0]=self.selectedTSS.staff
			self.tssValues[0].set(self.listObject[0].lname+" - "+self.listObject[0].fname)
			# Affichage du Status dans la ComboBox
			status = ( (u"E", 0), (u"V", 1), (u"L", 2), (u"A", 3), )
			for n in status:
				if n[0] == self.selectedTSS .checked: self.statusTSSCB.selectitem(n[1])
			# Affichage de la date de Début (self.selectedTSS .dateIn)
			self.tssValues[2].set(self.selectedTSS .dateIn.strftime("%d/%m/%Y"))
			# Affichage de l"heure de Début dans la ComboBox 
			count = 0
			for h in self.hoursListCB:
				if h == self.selectedTSS .dateIn.strftime("%H"): self.hourInTSSCB.selectitem(count)
				count+=1
			# Affichage des minutes de Début dans la ComboBox
			count = 0
			for m in self.minutesListCB:
				if m == self.selectedTSS .dateIn.strftime("%M"): self.minInTSSCB.selectitem(count)
				count+=1
			# Mise à jour des variables heure et minutes de Début
			self.tssHourIn.set(self.selectedTSS .dateIn.strftime("%H"))
			self.tssMinuteIn.set(self.selectedTSS .dateIn.strftime("%M"))
			# Affichage de la date de Fin (self.selectedTSS .dateOut)
			self.tssValues[4].set(self.selectedTSS .dateOut.strftime("%d/%m/%Y"))
			# Affichage de l"heure de Fin dans la ComboBox 
			count = 0
			for h in self.hoursListCB:
				if h == self.selectedTSS .dateOut.strftime("%H"): self.hourOutTSSCB.selectitem(count)
				count+=1
			# Affichage des minutes de Fin dans la ComboBox
			count = 0
			for m in self.minutesListCB:
				if m == self.selectedTSS .dateOut.strftime("%M"): self.minOutTSSCB.selectitem(count)
				count+=1
			# Mise à jour des variables heure et minutes de Fin
			self.tssHourOut.set(self.selectedTSS .dateOut.strftime("%H"))
			self.tssMinuteOut.set(self.selectedTSS .dateOut.strftime("%M"))
			# activation du bouton supprimer
			self.deleteTSSBt.config(state=NORMAL)

	def searchTimeSheetStaff(self, event=None):
		if self.listObject[0] != Staff:
			if self.searchTSSValue.get() != "":
				self.listTSS.delete(0,END)
				self.idListTSS = []
				result = TimeSheetStaff.select(AND(TimeSheetStaff.q.description.startswith(self.searchTSSValue.get().encode("utf-8")), TimeSheetStaff.q.staff==self.listObject[0]), orderBy=TimeSheetStaff.q.dateIn)
				for row in result:
					self.listTSS.insert(END, row.dateIn.strftime("%d/%m/%Y %H:%M")+" au "+row.dateOut.strftime("%d/%m/%Y %H:%M")+" - "+row.description)
					self.idListTSS.append(row.id)
			else:
				self.listTSS.delete(0,END)
				self.idListTSS = []
				result = TimeSheetStaff.select(TimeSheetStaff.q.staff==self.listObject[0], orderBy=TimeSheetStaff.q.dateIn)
				for row in result:
					self.listTSS.insert(END, row.dateIn.strftime("%d/%m/%Y %H:%M")+" au "+row.dateOut.strftime("%d/%m/%Y %H:%M")+" - "+row.description)
					self.idListTSS.append(row.id)
		else:
			showerror(u"Erreur de recherche", u"Commencer par séléctionner un Employé pour afficher la liste de ces Tâches")

	def makeTimeSheetStaff(self):
		leftFrame = Frame(self)
		# Fiche TimeSheetStaff  (présentation colonne de gauche)
		Label(leftFrame, text=u"Tâche").pack(side=TOP, fill=X)
		tssLabels = (u"Employé", u"Tâche", u"Début (date)", u"Début (heure)", u"Fin (date)", u"Fin (heure)", u"Status", u"Notes")
		self.tssValues = [StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar()]
		statusTSS = (u"En attente", u"Validé", u"En litige", u"Annulé")
		count = 0
		for name in tssLabels:
			f = Frame(leftFrame)
			Label(f, width=12, text=name, anchor=W).pack(side=LEFT)
			if count == 0: # Staff
				Entry(f, textvariable=self.tssValues[count], state=DISABLED, bd=0, disabledforeground="black").pack(side=LEFT, fill=X)
				myStaff=Button(f, image=self.imgSearch, command=lambda x=self.tssValues[count]:self.ctrlListStaff(x), padx=4, pady=1)
				myStaff.pack(side=RIGHT)
				self.balloon.bind(myStaff, u"Séléctionner un employé")
			elif count == 2: # Date debut
				Entry(f, textvariable=self.tssValues[count], width=21).pack(side=LEFT, fill=X)
				myCal1=Button(f, image=self.imgCalendar, command=lambda x=self.tssValues[count]:self.ctrlCalendar(x), padx=1, pady=1)
				myCal1.pack(side=LEFT)
				self.balloon.bind(myCal1, u"Calendrier")
			elif count == 3: 
				hStartLb1=Label(f, width=2, text="H", anchor=W)
				hStartLb1.pack(side=LEFT)
				self.balloon.bind(hStartLb1, u"Heure")
				self.hourInTSSCB=Pmw.ComboBox(f, selectioncommand=self.tssHourIn, scrolledlist_items=self.hoursListCB, listheight=100)
				self.hourInTSSCB._entryfield._entryFieldEntry.config( width = 3)
				self.hourInTSSCB.pack(side=LEFT)
				mStartLb1=Label(f, width=3, text="mn", anchor=W)
				mStartLb1.pack(side=LEFT)
				self.balloon.bind(mStartLb1, u"minutes")
				self.minInTSSCB=Pmw.ComboBox(f, selectioncommand=self.tssMinuteIn, scrolledlist_items=self.minutesListCB, listheight=100)
				self.minInTSSCB._entryfield._entryFieldEntry.config( width = 3)
				self.minInTSSCB.pack(side=LEFT)
				# Menu Time
				myTime1=Button(f, image=self.imgTime, padx=1, pady=1)
				myTime1.pack(side=RIGHT)
				myTime1.bind("<ButtonRelease-1>",self.ctrlTimeNow1)
				self.balloon.bind(myTime1, u"Séléctionner une heure")
			elif count == 4: # Date Fin
				Entry(f, textvariable=self.tssValues[count], width=21).pack(side=LEFT, fill=X)
				myCal2=Button(f, image=self.imgCalendar, command=lambda x=self.tssValues[count]:self.ctrlCalendar(x), padx=1, pady=1)
				myCal2.pack(side=LEFT)
				self.balloon.bind(myCal2, u"Calendrier")
			elif count == 5:
				hStartLb2=Label(f, width=2, text="H", anchor=W)
				hStartLb2.pack(side=LEFT)
				self.balloon.bind(hStartLb2, u"Heure")
				self.hourOutTSSCB=Pmw.ComboBox(f, selectioncommand=self.tssHourOut, scrolledlist_items=self.hoursListCB, listheight=100)
				self.hourOutTSSCB._entryfield._entryFieldEntry.config( width = 3)
				self.hourOutTSSCB.pack(side=LEFT)
				mStartLb2=Label(f, width=3, text="mn", anchor=W)
				mStartLb2.pack(side=LEFT)
				self.balloon.bind(mStartLb2, u"minutes")
				self.minOutTSSCB=Pmw.ComboBox(f, selectioncommand=self.tssMinuteOut, scrolledlist_items=self.minutesListCB, listheight=100)
				self.minOutTSSCB._entryfield._entryFieldEntry.config( width = 3)
				self.minOutTSSCB.pack(side=LEFT)
				# Menu Time
				myTime2=Button(f, image=self.imgTime, padx=1, pady=1)
				myTime2.pack(side=RIGHT)
				myTime2.bind("<ButtonRelease-1>",self.ctrlTimeNow2)
				self.balloon.bind(myTime2, u"Séléctionner une heure")
			elif count == 6: # Status
				self.statusTSSCB=Pmw.ComboBox(f, selectioncommand=self.tssStatus, scrolledlist_items=statusTSS, listheight=100)
				self.statusTSSCB._entryfield._entryFieldEntry.config( width = 21)
				self.statusTSSCB.pack(side=LEFT, fill=X)
				self.statusTSSCB.selectitem(0)
			elif count == 7: # Notes
				Entry(f, textvariable=self.tssValues[count], width=21).pack(side=LEFT, fill=X)
				myNotes=Button(f, image=self.imgNotes, command=lambda x=self.tssValues[count]:self.ctrlNotes(x,u"Notes"), padx=1, pady=1)
				myNotes.pack(side=LEFT)
				self.balloon.bind(myNotes, u"Détails de la note")
			else: 
				Entry(f, textvariable=self.tssValues[count], width=24).pack(side=LEFT, fill=X)
			f.pack(side=TOP, fill=X)
			count += 1
		# Boutons enregistrement (new ou modify) et suppression
		s = Frame(leftFrame) 
		self.saveTSSBt=Button(s, image=self.imgSave, command=self.createTimeSheetStaff)
		self.saveTSSBt.bind("<Return>", self.createTimeSheetStaff)
		self.saveTSSBt.pack(side=LEFT)
		self.balloon.bind(self.saveTSSBt, u"Enregistrer")
		self.deleteTSSBt=Button(s, image=self.imgDelete, command=self.deleteTimeSheetStaff, state=DISABLED)
		self.deleteTSSBt.bind("<Return>", self.deleteTimeSheetStaff)
		self.deleteTSSBt.pack(side=LEFT)
		self.balloon.bind(self.deleteTSSBt, u"Supprimer")
		s.pack(side=TOP, fill=X)
		leftFrame.pack(side=LEFT, fill=X)
		# Liste des TimeSheetStaff existantes (présentation colonne de droite)
		rightFrame = Frame(self) 
		Label(rightFrame, text=u"Liste des Tâches de l'employé séléctionné").pack(side=TOP, fill=X)
		self.searchTSSValue = StringVar()
		s = Frame(rightFrame)
		self.searchTaskEt = Entry(s,  width=60, textvariable=self.searchTSSValue, relief=GROOVE)
		self.searchTaskEt.bind("<KeyRelease>", self.searchTimeSheetStaff)
		self.searchTaskEt.pack(side=LEFT, fill=X)
		self.balloon.bind(self.searchTaskEt, u"Saisir les premières lettres d'une tâche\npour une recherche plus précise,\nla liste est classée par date de début.")
		myTimeSheet=Button(s, image=self.imgSearch, command=self.searchTimeSheetStaff, padx=4, pady=1)
		myTimeSheet.pack(side=RIGHT)
		self.balloon.bind(myTimeSheet, u"Rechercher des Tâches")
		s.pack(side=TOP, fill=X)
		s = Frame(rightFrame) 
		scrollbar = Scrollbar(s)
		scrollbar.pack(side=RIGHT, fill=Y)
		self.listTSS = Listbox(s)
		self.listTSS.config(yscrollcommand=scrollbar.set, width=60, selectmode=SINGLE, height=12)
		self.listTSS.bind("<ButtonRelease-1>",self.selectTimeSheetStaff)
		scrollbar.config(command=self.listTSS.yview)
		self.listTSS.pack()
		self.balloon.bind(self.listTSS, u"Séléctionner une tâche\npour la visualiser ou la modifier.")
		s.pack(side=TOP, fill=X)
		rightFrame.pack(side=RIGHT, fill=X)
		# Initialisation
		self.clearFieldTSS()

	def ctrlTimeNow1(self,event):
		varHour=[self.tssHourIn, self.tssMinuteIn, self.hourInTSSCB, self.minInTSSCB] 
		TimePopupGUI(self, event=event, field=self.tssValues[3], varHour=varHour, log=self.log, path=self.path)

	def ctrlTimeNow2(self,event):
		varHour=[self.tssHourOut, self.tssMinuteOut, self.hourOutTSSCB, self.minOutTSSCB]
		TimePopupGUI(self, event=event, field=self.tssValues[5], varHour=varHour, log=self.log, path=self.path)

	def ctrlCalendar(self,field):
		CalendarGUI(field=field, log=self.log, path=self.path)

	def ctrlListStaff(self,field):
		StaffListGUI(balloon=self.balloon, field=field, index=0, listObject=self.listObject, log=self.log, path=self.path)

	def ctrlNotes(self,field,title):
		NotesGUI(field=field,title=title, log=self.log, path=self.path)

	def tssStatus(self, value):
		status = (  (u"E", u"En attente"), (u"V", u"Validé"), (u"L", u"En litige"), (u"A", u"Annulé"), ) 
		for n in status:
			if n[1] == value: self.tssValues[6].set(n[0])

	def tssHourIn(self, value):
		self.tssHourIn.set(value)
		self.minInTSSCB.selectitem(0)
		self.minInTSSCB.invoke()

	def tssMinuteIn(self, value):
		self.tssMinuteIn.set(value)

	def tssHourOut(self, value):
		self.tssHourOut.set(value)
		self.minOutTSSCB.selectitem(0)
		self.minOutTSSCB.invoke()

	def tssMinuteOut(self, value):
		self.tssMinuteOut.set(value)

	def getDateTimeInTSS(self):
		# Récuperer l"année
		date=self.tssValues[2].get().split("/")
		d = datetime.datetime(int(date[2]), int(date[1]), int(date[0]), int(self.tssHourIn.get()), int(self.tssMinuteIn.get()), 0)
		return d

	def getDateTimeOutTSS(self):
		# Récuperer l"année
		date=self.tssValues[4].get().split("/")
		d = datetime.datetime(int(date[2]), int(date[1]), int(date[0]), int(self.tssHourOut.get()), int(self.tssMinuteOut.get()), 0)
		return d

	def verifyTimeSheetStaff(self):
		if self.tssValues[0].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Employé est obligatoire !\nMerci de le compléter.")
			return False
		elif self.tssValues[1].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Tâche est obligatoire !\nMerci de le compléter.")
			return False
		elif self.tssValues[2].get() == "": # TODO Créer une fonction validDate()
			showerror(u"Erreur de saisie", u"Le champ Date début est obligatoire !\nMerci de le compléter.")
			return False
		elif self.tssHourIn.get() == "" or  self.tssMinuteIn.get() == "": # TODO Créer une fonction validTime()
			showerror(u"Erreur de saisie", u"Les champs Heures et Minutes début sont obligatoire !\nMerci de le compléter.")
			return False
		elif self.tssValues[4].get() == "": # TODO Créer une fonction validDate()
			showerror(u"Erreur de saisie", u"Le champ Date fin est obligatoire !\nMerci de le compléter.")
			return False
		elif self.tssHourOut.get() == "" or  self.tssMinuteOut.get() == "": # TODO Créer une fonction validTime()
			showerror(u"Erreur de saisie", u"Les champs Heures et Minutes fin sont obligatoire !\nMerci de le compléter.")
			return False
		elif self.tssValues[6].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Status est obligatoire !\nMerci de le compléter.")
			return False
		else:
			return True

	def createTimeSheetStaff(self, event=None):
		if self.verifyTimeSheetStaff():
			if  self.deleteTSSBt.config()["state"][4] == "normal":
				self.modifyTimeSheetStaff()
			else:
				if askyesno(u"Enregistrement", u"Souhaitez-vous enregistrer %s comme un nouveau Emplois du Temps ?\n" % self.tssValues[1].get()):
					TimeSheetStaff(staff=self.listObject[0],
						description=self.tssValues[1].get().encode("utf-8"),
						dateIn=self.getDateTimeInTSS(),
						dateOut=self.getDateTimeOutTSS(),
						checked=self.tssValues[6].get().encode("utf-8"),
						notes=self.tssValues[7].get().encode("utf-8"),
						createDate=datetime.datetime.now()
					)
					self.searchTimeSheetStaff()
				self.clearFieldTSS()

	def modifyTimeSheetStaff(self, event=None): 
		if askyesno(u"Modifier", u"Souhaitez-vous modifier l'Emplois du Temps %s ?" % self.selectedTSS.description):
			self.selectedTSS.staff=self.listObject[0]
			self.selectedTSS.description=self.tssValues[1].get().encode("utf-8")
			self.selectedTSS.dateIn=self.getDateTimeInTSS()
			self.selectedTSS.dateOut=self.getDateTimeOutTSS()
			self.selectedTSS.checked=self.tssValues[6].get().encode("utf-8")
			self.selectedTSS.notes=self.tssValues[7].get().encode("utf-8")
			self.searchTimeSheetStaff()
		self.deleteTSSBt.config(state=DISABLED)
		self.clearFieldTSS()

	def deleteTimeSheetStaff(self, event=None): 
		if askyesno(u"Suppression", u"Souhaitez-vous supprimer l'Emplois du Temps %s ?\nCette opération est irréversible !" % self.selectedTSS.description):
			TimeSheetStaff.delete(self.selectedTSS.id)
			self.searchTimeSheetStaff()            
		self.deleteTSSBt.config(state=DISABLED)
		self.clearFieldTSS()
	# FIN de la gestion du module TimeSheetStaff ---------------------------------------------------------------------------------------------------